#include <string.h>
#include <iostream>

using namespace std;

class CowString{
public:
    CowString()
        :_pstr(new char[1+4]()+4)
    {
        *(int *)(_pstr-4) = 1;
    }
    ~CowString(){
        if(--*(int *)(_pstr-4) == 0){
            delete [] (_pstr-4);
            _pstr = nullptr;
        }

    }
    CowString(const char *pstr)
        :_pstr(new char [strlen(pstr)+1+4]()+4)
    {
        strcpy(_pstr,pstr);
        *(int *)(_pstr-4) = 1;
    }

    CowString(const CowString &rhs)
        :_pstr(rhs._pstr)
    {
        ++ *(int *)(_pstr-4) = 1;
    }

    CowString &operator=(const CowString &rhs){
        if(this != &rhs){
            if(--*(int *)(_pstr -4) == 0){
                delete [] (_pstr-4);
            }
            _pstr = rhs._pstr;
            ++*(int *)(_pstr-4);
        }
        return *this;
    }
    int refcount() const{
        return *(int *)(_pstr-4);
    }
 
friend ostream &operator<<(ostream & os,CowString &rhs);

private:
    char * _pstr;

};

ostream &operator<<(ostream & os,CowString &rhs){
    os << rhs._pstr;
    return os;
} 


void test(){
    CowString s1 = "hello";
    cout << s1 << ":" << s1.refcount() << endl;
    CowString s2 = s1;
    cout << s1 << ":" << s1.refcount() << endl;
    cout << s2 << ":" << s2.refcount() << endl;
    CowString s3 = "world";
    cout << "赋值运算操作" << endl;
    s2 = s3;
    cout << s3 << ":" << s3.refcount() << endl;
    cout << s2 << ":" << s2.refcount() << endl;
    cout << s1 << ":" << s1.refcount() << endl;
    s1 = s3;
    cout << s3 << ":" << s3.refcount() << endl;
    cout << s2 << ":" << s2.refcount() << endl;
    cout << s1 << ":" << s1.refcount() << endl;
}

int main()
{
    test();
    return 0;
}

